<?php

/*------------------------------------------------------------------------
# com_invoices - Invoices for Joomla
# ------------------------------------------------------------------------
# author				Germinal Camps
# copyright 			Copyright (C) 2012 JoomlaFinances.com. All Rights Reserved.
# @license				http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL
# Websites: 			http://www.JoomlaFinances.com
# Technical Support:	Forum - http://www.JoomlaFinances.com/forum
-------------------------------------------------------------------------*/

//no direct access
defined('_JEXEC') or die('Restricted access.');
 
class InvoicesHelper{
	
	static function showInvoicesFooter(){
		require_once(JPATH_SITE.DS.'components'.DS.'com_invoices'.DS.'helpers'.DS.'version.php');
		return InvoicesVersion::show_footer();
	}
	
	static function format($number, $before = "", $after = ""){
		
		$params = JComponentHelper::getParams( 'com_invoices' );
		
		$decpoint = $params->get('decpoint', '.');
		$thousands = $params->get('thousands', ',');
		
		return $before  . number_format($number, 2, $decpoint, $thousands)  . $after ;
	}

	static function format_simple($number){
		
		
		return str_replace(".", ",", $number) ;
	}
	
	static function get_subtotal($invoice_id){
		
		$db = JFactory::getDBO();
		
		//$query = ' SELECT SUM(it.value * it.amount - it.discount) FROM #__invoices_items AS it WHERE it.invoice_id = '.$invoice_id ;
		$query = ' SELECT SUM((it.value * it.amount - it.discount)*(1+it.tax/100)) FROM #__invoices_items AS it WHERE it.invoice_id = '.$invoice_id ;
		$db->setQuery($query);
		$subtotal = $db->loadResult();
		
		$query = ' SELECT discount FROM #__invoices_invoices AS i WHERE i.id = '.$invoice_id ;
		$db->setQuery($query);
		$discount = $db->loadResult();

		return $subtotal - $discount;
	
	}
	
	static function get_total($invoice){
		
		$db = JFactory::getDBO();
		
		$taxes_value = 0;
		$thetaxvalue = 0 ;
		
		$subtotal1 = $invoice->subtotal ;
		
		if($invoice->taxes){
			$query = ' SELECT * FROM #__invoices_taxes WHERE id IN('.$invoice->taxes.') ORDER BY ordering, name ' ;
			$db->setQuery($query);
			$taxes = $db->loadObjectList();
			
			foreach($taxes as $tax){
				switch($tax->type){
					case "percent":
						
						if($tax->ordering == 1){ //first group of taxes
							$thetaxvalue = ( $tax->value / 100 ) * $invoice->subtotal ;
							$taxes_value += ( $tax->value / 100 ) * $invoice->subtotal ;
						}
						else if($tax->ordering == 2){ //second group of taxes
							$thetaxvalue = ( $tax->value / 100 ) * $subtotal1 ;
							$taxes_value += ( $tax->value / 100 ) * $subtotal1 ;
						}
				
					break;
					case "static":
						$taxes_value += $tax->value ;
					break;
				}
				
				if($tax->ordering == 1){
					$subtotal1 += $thetaxvalue ;
				}
			}
			
		}
		
		$total = $invoice->subtotal + $taxes_value ;

		return $total;
	
	}
	
	static function get_total_from_id($invoice_id){
		$db = JFactory::getDBO();
		$query = ' SELECT * FROM #__invoices_invoices WHERE id = ' . $invoice_id ;
		$db->setQuery($query);
		$invoice = $db->loadObject();
			
		$invoice->subtotal = InvoicesHelper::get_subtotal($invoice_id);
		
		$total = InvoicesHelper::get_total($invoice);
		
		return $total;
	}
	
	static function download_pdf_button($id){
		
		$version = PHP_VERSION >= 5.0 ? true : false ;
		$quotes = get_magic_quotes_gpc();
		//echo $quotes;die;
		if(file_exists(JPATH_SITE.DS.'components'.DS.'com_invoices'.DS.'helpers'.DS.'dompdf'.DS.'dompdf_config.inc.php') && $version && !$quotes){
			
			$mainframe = JFactory::getApplication();
			$uri = JFactory::getURI();
			
			
			if(!$mainframe->isSite()){
				//$url = $uri->root().'index.php?option=com_invoices&view=invoice&format=dompdf&id='.$id;
				$url = JRoute::_('index.php?option=com_invoices&view=invoice&format=dompdf&cid[]='.$id);
			}
			else $url = JRoute::_('index.php?option=com_invoices&view=invoice&format=dompdf&id='.$id);
		
		
			$return = "<a href='".$url."' title=\"".JText::_('DOWNLOAD_INVOICE_PDF')."\">".JHTML::image('components/com_invoices/assets/images/page_white_acrobat.png', JText::_('DOWNLOAD_INVOICE_PDF'))."</a>" ;
		}
		else $return = "";
		return $return ;
	
	}
	
	static function view_modal_button($id){
		
		$modal = true ;
		
		if($modal){
			$link = "&tmpl=component" ;
			$rel = 'rel="{ size: {x: 800, y: 500}, handler: \'iframe\'}"';
		}
		
		$mainframe = JFactory::getApplication();
		$uri = JFactory::getURI();
		
		$url = JRoute::_('index.php?option=com_invoices&view=invoice&id='.$id.$link);
		
		if(!$mainframe->isSite()){
			//$url = $uri->root().'index.php?option=com_invoices&view=invoice&id='.$id.$link;
			$url = JRoute::_('index.php?option=com_invoices&view=invoice&cid[]='.$id.$link);
		}
		
		$return = "<a class='modal' ".$rel." href='".$url."' title=\"".JText::_('VIEW_INVOICE_DETAILS')."\">".JHTML::image('components/com_invoices/assets/images/magnifier.png', JText::_('VIEW_INVOICE_DETAILS'))."</a>" ;
		return $return ;
	
	}
	
	static function view_online_button($id){
		
		$mainframe = JFactory::getApplication();
		$uri = JFactory::getURI();
		
		$url = JRoute::_('index.php?option=com_invoices&view=invoice&id='.$id );
		
		if(!$mainframe->isSite()){
			//$url = $uri->root().'index.php?option=com_invoices&view=invoice&id='.$id.'&tmpl=component';
			$url = JRoute::_('index.php?option=com_invoices&view=invoice&cid[]='.$id.'&tmpl=component');
		}
		
		$return = "<a target='_blank' href='".$url."' title=\"".JText::_('VIEW_INVOICE_ONLINE')."\">".JHTML::image('components/com_invoices/assets/images/invoice.png', JText::_('VIEW_INVOICE_ONLINE'))."</a>" ;
		return $return ;
	
	}
	
	
	static function send_email_button($id, $type = "invoice"){
		
		$mainframe = JFactory::getApplication();
		
		if(!$mainframe->isSite()){
			$url = JRoute::_('index.php?option=com_invoices&controller='.$type.'&task=send_email&cid[]='.$id);
		}
		else{
			$url = JRoute::_('index.php?option=com_invoices&task=send&id='.$id);
		}
		
		$return = "<a href='".$url."' title=\"".JText::_('SEND_EMAIL')."\">".JHTML::image('components/com_invoices/assets/images/email.png', JText::_('SEND_EMAIL'))."</a>" ;
		return $return ;
	
	}
	
	
	function create_invoice($data, $items, $payments){
		$mainframe = JFactory::getApplication();
		$model = InvoicesHelper::getInvoiceAdminModel();
		require_once( JPATH_SITE.DS.'administrator'.DS.'components'.DS.'com_invoices'.DS.'tables'.DS.'invoice.php' );
		require_once( JPATH_SITE.DS.'administrator'.DS.'components'.DS.'com_invoices'.DS.'tables'.DS.'contact.php' );
		require_once( JPATH_SITE.DS.'administrator'.DS.'components'.DS.'com_invoices'.DS.'tables'.DS.'item.php' );
		require_once( JPATH_SITE.DS.'administrator'.DS.'components'.DS.'com_invoices'.DS.'tables'.DS.'payment.php' );
		if ($model->store($data, $items, $payments)) {
			$msg = JText::_( 'Invoice created!' );
			$type = "message" ;
		} else {
			$msg = JText::_( 'Error creating Invoice' );
			$type = "error" ;
		}
		$mainframe->enqueueMessage($msg, $type);
	}
	
	function getInvoiceAdminModel()
	{
		if (!class_exists( 'InvoicesModelInvoice' ))
		{
			// Build the path to the model based upon a supplied base path
			$path = JPATH_SITE.DS.'administrator'.DS.'components'.DS.'com_invoices'.DS.'models'.DS.'invoice.php';
			$false = false;

			// If the model file exists include it and try to instantiate the object
			if (file_exists( $path )) {
				require_once( $path );
				if (!class_exists( 'InvoicesModelInvoice' )) {
					JError::raiseWarning( 0, 'View class InvoicesModelInvoice not found in file.' );
					return $false;
				}
			} else {
				JError::raiseWarning( 0, 'View InvoicesModelInvoice not supported. File not found.' );
				return $false;
			}
		}

		$model = new InvoicesModelInvoice();
		return $model;
	}
	
	static function getStatus(){
		$status = array();
		$status[] = "preliminary";
		$status[] = "paid";
		$status[] = "pending";	
		$status[] = "partial_paid";	
		$status[] = "pastdue";	
		$status[] = "refunded";
		$status[] = "partial_refunded";
		
		return $status;
	}

	static function getQuoteStatus(){
		$status = array();
		
		$status[] = "pending";	
		$status[] = "accepted";	
		$status[] = "accepted_client";	
		$status[] = "cancelled";
		$status[] = "rejected";
		$status[] = "rejected_client";
		$status[] = "expired";
		
		return $status;
	}
	
	static function getStatusPaymentFilters(){
		$status = array();
		
		$status['unpaid'] = JText::_('UNPAID_SIMPLE');
		$status['paid'] = JText::_('PAID');
		$status['pending'] = JText::_('PENDING_VALIDATION');
		
		return $status;
	}
	
	static function getPaymentStatus(){
		$status = array();
		
		$status[0] = JText::_('UNPAID');
		$status[1] = JText::_('PAID');
		$status[2] = JText::_('UNPAID_ONTIME');
		$status[3] = JText::_('PENDING_VALIDATION');
		
		return $status;
	}
	
	function getPaymentData($payment_id){
		
		$db = JFactory::getDBO();
		
		$query = ' SELECT pa.* FROM #__invoices_payments AS pa WHERE pa.id = '.$payment_id;
		$db->setQuery($query);
		$payment = $db->loadObject();
		
		return $payment;
		
	}
	
	function getNextRecurrencyDate($invoice){
		
		if($invoice["rec_year"]) $months = $invoice["rec_year"] * 12 + $invoice["rec_month"] ;
		else $months = $invoice["rec_month"] ;
		
		$thetime = $invoice["rec_nextdate"] . " + ".$months." months + ".$invoice["rec_day"]." days" ;
		//echo $thetime;die;
		
		$nextdate = strtotime($thetime) ;
		$nextdate = date("Y-m-d", $nextdate) ;
		
		return $nextdate ;
		
	}

	static function getPaymentLink($payment_id){
		$uri = JFactory::getURI();
		
		$link = $uri->base() . 'index.php?option=com_invoices&view=payment&id='.$payment_id ;
		$link = str_replace("administrator/","",$link) ;
		return $link;
	}

	static function getInvoiceLink($invoice_id){
		$uri = JFactory::getURI();
		
		$link = $uri->base() . 'index.php?option=com_invoices&view=invoice&id='.$invoice_id ;
		$link = str_replace("administrator/","",$link) ;
		return $link;
	}

	static function getInvoicePublicLink($invoice_id){
		$uri = JFactory::getURI();
		$db = JFactory::getDBO();

		$query = " SELECT auth_code FROM #__invoices_invoices WHERE id = ".$invoice_id ;
		$db->setQuery($query);
		$auth_code = $db->loadResult();
		
		$link = $uri->base() . 'index.php?option=com_invoices&view=invoice&id='.$invoice_id .'&auth_code='.$auth_code;
		$link = str_replace("administrator/","",$link) ;
		return $link;
	}
	
	static function getInvoiceNum($real_invoice_num, $type = 1){
		$params = JComponentHelper::getParams( 'com_invoices' );
		if($type == 1) $format = $params->get('invoice_num_format') ;
		elseif($type == 2) $format = $params->get('quote_num_format') ;
		
		$string = str_replace("[num]", $real_invoice_num, $format) ;
		$string = str_replace("[yyyy]", date("Y"), $string) ;
		$string = str_replace("[mm]", date("m"), $string) ;
		$string = str_replace("[dd]", date("d"), $string) ;

		return $string ;
			
	}

	static function getInvoiceStatus($invoice, $total, $total_payments, $amount_outstanding){

		$params = JComponentHelper::getParams( 'com_invoices' );

		$status = $invoice->status ;
		if(!$status && $params->get('computestatus')){
			//if the status is not set, we calculate it

			$status = InvoicesHelper::getComputedInvoiceStatus($invoice, $total, $total_payments, $amount_outstanding);

		}

		return $status;
	}

	static function getComputedInvoiceStatus($invoice, $total, $total_payments = false, $amount_outstanding = false){

		$db = JFactory::getDBO();

		if(!$total_payments){
			$query = " SELECT SUM(payment_amount) FROM #__invoices_payments WHERE payment_status = 1 AND invoice_id = ".$invoice->id ;
			$db->setQuery($query);
			$total_payments = $db->loadResult();
		}
		if(!$amount_outstanding){
			$query = " SELECT SUM(payment_amount) FROM #__invoices_payments WHERE payment_status = 0 AND invoice_id = ".$invoice->id ;
			$db->setQuery($query);
			$amount_outstanding = $db->loadResult();
		}

		if($amount_outstanding == 0 && $total_payments >= $total){
			$status = "paid"; //paid in full
		}
		elseif($invoice->invoice_duedate != "0000-00-00" && $invoice->invoice_duedate != "0000-00-00 00:00:00" ){
			if(strtotime($invoice->invoice_duedate) <= time()) {
				$status = "pastdue"; //past due date
			}
			else {
				if($amount_outstanding && $total_payments){
					$status = "partial_paid"; //partially paid
				}
				else $status = "pending"; //pending
			}
		}
		elseif($invoice->invoice_duedate == "0000-00-00" || $invoice->invoice_duedate == "0000-00-00 00:00:00" || !$invoice->invoice_duedate){
			
			if($amount_outstanding && $total_payments){
				$status = "partial_paid"; //partially paid
			}
			elseif($total_payments){
				$status = "partial_paid"; //partially paid
			}
			else $status = "pending"; //pending
		}

		return $status;
	}

	static function updateComputedStatus($invoice_id, $calculate_total = false, $create_auth_code = false){
		$db = JFactory::getDBO();

		$query = " SELECT * FROM #__invoices_invoices WHERE id = ".$invoice_id ;
		$db->setQuery($query);
		$invoice = $db->loadObject();

		$sql_total = "";
		$sql_auth_code = "";

		if($calculate_total) {
			$computed_total = InvoicesHelper::get_total_from_id($invoice->id) ;
			$sql_total = ', computed_total = '.$computed_total ; 
		}
		else $computed_total = $invoice->computed_total ;

		if(!$invoice->auth_code) {
			$auth_code = InvoicesHelper::genRandomCode() ;
			$sql_auth_code = ', auth_code = "'.$auth_code.'" ' ; 
		}
		else $sql_auth_code = "" ;

		$computed_status = InvoicesHelper::getComputedInvoiceStatus($invoice, $computed_total) ;

		$query = 	' UPDATE #__invoices_invoices SET '.
					' computed_status =  "'.$computed_status.'" '.
					$sql_total .
					$sql_auth_code .
					' WHERE id = '.$invoice_id .
					' LIMIT 1 ';
		
		$db->setQuery($query);
		$db->query();
	}

	static function render_status($status){
		switch($status){
			case "paid": case "payed": case "accepted": case "accepted_client":
			$status = "<span class='label label-success'>".JText::_($status)."</span>" ;
			break;
			case "pending":case "partial_paid":case "preliminary":
			$status = "<span class='label label-warning'>".JText::_($status)."</span>" ;
			break;
			case "pastdue": case "rejected": case "rejected_client":
			$status = "<span class='label label-important'>".JText::_($status)."</span>" ;
			break;
			case "refunded": case "partial_refunded": case "cancelled": case "expired":
			$status = "<span class='label label-inverse'>".JText::_($status)."</span>" ;
			break;
			default:
			$status = "<span class='label'>".JText::_("NOT_SETTED")."</span>" ;
			break;
		}

		return $status;
	}

	static function getThePaymentStatus($payment){

		if($payment->payment_status){
			$thestatus = 1;
			
		}
		elseif($payment->payment_duedate != "0000-00-00 00:00:00" && !$payment->payment_status){
			if(strtotime($payment->payment_duedate) <= time()) {
				
				$thestatus = 0;
				
			}
			else {
				
				$thestatus = 2;
				
			}
		}
		elseif($payment->payment_duedate == "0000-00-00 00:00:00"){
			$thestatus = 2;
			
		}
		
		if($payment->payment_status == 2){
			$thestatus = 3;
			
		}

		return $thestatus ;
	}
	
	static function render_status_payment($status){

		$payment_status = InvoicesHelper::getPaymentStatus();
		
		switch($status){
			case 0:
			$status = "<span class='label label-important'>".$payment_status[$status]."</span>" ;
			break;
			case 1:
			$status = "<span class='label label-success'>".$payment_status[$status]."</span>" ;
			break;
			case 2:
			$status = "<span class='label label-warning'>".$payment_status[$status]."</span>" ;
			break;
			case 3:
			$status = "<span class='label'>".$payment_status[$status]."</span>" ;
			break;
		}

		return $status;
	}

	static function render_num_payments_received($num){

		switch($num){
			case 0:
			$status = "<span class='badge'>".$num."</span>" ;
			break;
			default:
			$status = "<span class='badge badge-success'>".$num."</span>" ;
			break;
		}

		return $status;
	}

	static function render_num_pending_payments($num){

		switch($num){
			case 0:
			$status = "<span class='badge'>".$num."</span>" ;
			break;
			default:
			$status = "<span class='badge badge-warning'>".$num."</span>" ;
			break;
		}

		return $status;
	}

	static function PDFavailable(){
		$version = PHP_VERSION >= 5.0 ? true : false ;
		$quotes = get_magic_quotes_gpc();
		
		if(file_exists(JPATH_SITE.DS.'components'.DS.'com_invoices'.DS.'helpers'.DS.'dompdf'.DS.'dompdf_config.inc.php') && $version && !$quotes){
			return true;
		}
		else return false;
		
	}

	static function genRandomCode($length = 64)
	{
		$salt = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
		$base = strlen($salt);
		$makepass = '';

		/*
		 * Start with a cryptographic strength random string, then convert it to
		 * a string with the numeric base of the salt.
		 * Shift the base conversion on each character so the character
		 * distribution is even, and randomize the start shift so it's not
		 * predictable.
		 */
		$random = JCrypt::genRandomBytes($length + 1);
		$shift = ord($random[0]);

		for ($i = 1; $i <= $length; ++$i)
		{
			$makepass .= $salt[($shift + ord($random[$i])) % $base];
			$shift += ord($random[$i]);
		}

		return $makepass;
	}

	
}